package com.xiaoxu.rental.controller;

import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWTPayload;
import com.xiaoxu.rental.entity.Permission;
import com.xiaoxu.rental.entity.User;
import com.xiaoxu.rental.security.CustomerAuthenticationException;
import com.xiaoxu.rental.util.*;
import com.xiaoxu.rental.vo.RefreshTokenVo;
import com.xiaoxu.rental.vo.RouteVo;
import com.xiaoxu.rental.vo.UserInfoVo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Date 2024/7/26 12:39
 * @description: 刷新token
 */
@RestController
@RequestMapping("/rental/auth")
@SuppressWarnings("all")
public class AuthorizationTokenController {

   @Resource
   private RedisUtils redisUtils;

    @PostMapping("/refreshToken")
    public Result<RefreshTokenVo> refreshToken(HttpServletRequest request)
    {
        //获取token
        String token = request.getHeader("token");
        if (StrUtil.isEmpty(token)) {
            token = request.getParameter("token");
        }
        //从SecurityContextHolder上下文中获取Authentication
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        //从token中获取用户名
        String username = JwtUtils.parseToken(token).getClaim("username").toString();
        String newToken = "";
        if (StrUtil.equals(username, userDetails.getUsername())) {
            Map<String, Object> map = new HashMap<>();
            map.put("username", userDetails.getUsername());
            newToken = JwtUtils.createToken(map);
        } else {
            throw new CustomerAuthenticationException("token数据异常");
        }
        //获取本次token过期时间
        NumberWithFormat claim = (NumberWithFormat) JwtUtils.parseToken(newToken).getClaim(JWTPayload.EXPIRES_AT);
        DateTime dateTime = (DateTime) claim.convert(DateTime.class, claim);
        long expireTime = dateTime.getTime();
        //创建一个tokenVo的对象，将新生成的token和过期时间存入
        RefreshTokenVo tokenVo = new RefreshTokenVo();
        tokenVo.setToken(newToken).setExpireTime(expireTime);
        //清除原有token
        redisUtils.del("token:" + token);
        //将新的token存入redis
        long nowTime = DateTime.now().getTime();
        String newTokenKey = "token:" + newToken;
        redisUtils.set(newTokenKey, newToken, (expireTime - nowTime) / 1000);
        return Result.success(tokenVo).setMessage("刷新token成功");
}


    @GetMapping("/info")
    public Result getUseInfo(){
        //从上下文中获取token
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user == null){
            return  Result.fail().setMessage("用户未登录");

        }
//        List<String> roleNameList = userService.selectRoleByUserId(user.getId());
//        Object[] array = roleNameList.toArray();
        List<Permission> permissionList = user.getPermissionList();
        Object[] array = permissionList.stream().filter(Objects::nonNull)
                .map(Permission::getPermissionCode)
                .toArray();
        UserInfoVo userInfoVo =
                new UserInfoVo(user.getId(),
                        user.getUsername(),
                        array, user.getAvatar(),
                        user.getNickname());
        return Result.success(userInfoVo);
    }


    @GetMapping("/menuList")
    public Result getMenuList() {
        //获取当前用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            return Result.fail().setMessage("认证信息为空");
        }
        User user = (User) authentication.getPrincipal();
        //获取用户的权限列表
        List<Permission> permissionList = user.getPermissionList();
        //获取用户的菜单
        //将permission_type为2的按钮移除，不需要生成对应的菜单
        permissionList.removeIf(permission -> Objects.equals(permission.getPermissionType(), 2));
        List<RouteVo> routeVOList = RouteTreeUtils.buildRouteTree(permissionList, 0);
        return Result.success(routeVOList).setMessage("获取菜单列表成功");
    }
    @PostMapping("/logout")
    public Result logout(HttpServletRequest request, HttpServletResponse response){

        String token = request.getHeader("token");

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null){
            redisUtils.del("token:" + token);
        }

        //登出
        SecurityContextLogoutHandler securityContextLogoutHandler = new SecurityContextLogoutHandler();

        securityContextLogoutHandler.logout(request, response, authentication);

        return Result.success().setMessage("退出成功");
    }
}
